package world.xuewei.service.impl;

import ch.qos.logback.classic.Logger;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import world.xuewei.dao.CommodityDao;
import world.xuewei.dao.OrderItemDao;
import world.xuewei.model.entity.*;
import world.xuewei.dao.OrdersDao;
import world.xuewei.service.MerchantInfoService;
import world.xuewei.service.OrdersService;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 订单主表(Orders)表服务实现类
 *
 * @author makejava
 * @since 2024-11-16 15:40:07
 */
@Slf4j
@Service("ordersService")
public class OrdersServiceImpl implements OrdersService {
    @Resource
    private OrdersDao ordersDao;

    @Resource
    private OrderItemDao orderItemDao;

    @Resource
    private CommodityDao commodityDao;

    @Resource
    private MerchantInfoService merchantInfoService;

    @Resource
    private AlipayClient alipayClient;


    /**
     * 创建订单
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createOrder(Long userId,Long merchantId, Long addressId, String remark,Integer deliveryType, List<OrderItem> items) {
        // 1. 生成订单号
        String orderNumber = generateOrderNumber(userId);

        // 2. 计算订单总金额
        BigDecimal totalAmount = BigDecimal.ZERO;

        // 3. 创建订单主表记录
        Orders order = new Orders();
        order.setOrderNumber(orderNumber);
        order.setUserId(userId);
        order.setMerchantId(merchantId);
        order.setAddressId(addressId);
        order.setDeliveryType(deliveryType);
        order.setRemark(remark);
        order.setOrderStatus(0); // 待付款
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());

        // 4. 处理订单项
        for (OrderItem item : items) {
            // 获取商品信息
            Commodity commodity = commodityDao.queryById(item.getCommodityId());
            if (commodity == null) {
                throw new RuntimeException("商品不存在");
            }

            // 设置订单项信息
            item.setOrderNumber(orderNumber);
            item.setMerchantId(commodity.getMerchantId());
            item.setCommodityName(commodity.getName());
            item.setCommodityImg(commodity.getImg());
            item.setOriginalPrice(commodity.getOriginalPrice());
            item.setPurchasePrice(commodity.getNowPrice());

            // 计算额外费用
//            BigDecimal extraPrice = this.calculateExtraPrice(item);
//            item.setExtraPrice(extraPrice);

            // 计算小计金额
            BigDecimal subtotal = item.getPurchasePrice()
//                    .add(item.getExtraPrice())
                    .multiply(new BigDecimal(item.getQuantity()));
            item.setSubtotal(subtotal);
            item.setItemStatus(0); // 待发货

            // 累加总金额
            totalAmount = totalAmount.add(subtotal);

            // 扣减库存
            if (commodityDao.updateInventory(commodity.getId(), -item.getQuantity()) <= 0) {
                throw new RuntimeException("库存不足");
            }
        }


        // 5. 设置订单总金额
        order.setTotalAmount(totalAmount);
        order.setPayAmount(totalAmount); // 实付金额暂时等于总金额

        // 6. 保存订单
        ordersDao.insert(order);

        // 7. 设置订单项的订单ID并批量保存
        for (OrderItem item : items) {
            item.setOrderId(order.getId());
        }
        orderItemDao.insertBatch(items);

        return orderNumber;
    }

    //获取订单信息
    @Override
    public Orders getOrderDetail(String orderNumber) {
        if (orderNumber == null || orderNumber.trim().isEmpty()) {
            throw new IllegalArgumentException("订单号不能为空");
        }

        // 获取订单基本信息
        Orders order = ordersDao.getOrderDetail(orderNumber);
        if (order != null) {
            // 获取订单项列表
            List<OrderItem> orderItems = orderItemDao.queryByOrderNumber(orderNumber);
            order.setOrderItems(orderItems);

            // 获取收货地址信息
            if (order.getDeliveryType() == 0 && order.getAddressId() != null) {
                Address address = ordersDao.loadOrderAddress(order.getAddressId());
                order.setAddress(address);
            }

            // 获取商户信息
            if (!orderItems.isEmpty()) {
                Long merchantId = orderItems.get(0).getMerchantId();
                MerchantInfo merchantInfo = merchantInfoService.queryById(merchantId);
                order.setMerchantInfo(merchantInfo);
            }
        }
        return order;
    }


    //获取id用户订单信息
    @Override
    public List<Orders> getUserOrders(Long userId) {
        List<Orders> orders = ordersDao.queryByUserId(userId, null);
        // 加载每个订单的详细信息
        for (Orders order : orders) {
            // 获取订单项列表
            List<OrderItem> orderItems = orderItemDao.queryByOrderNumber(order.getOrderNumber());
            order.setOrderItems(orderItems);

            // 如果是外送订单，获取收货地址信息
            if (order.getDeliveryType() == 0 && order.getAddressId() != null) {
                Address address = ordersDao.loadOrderAddress(order.getAddressId());
                order.setAddress(address);
            }

            // 获取商户信息
            if (!orderItems.isEmpty()) {
                Long merchantId = orderItems.get(0).getMerchantId();
                MerchantInfo merchantInfo = merchantInfoService.queryById(merchantId);
                order.setMerchantInfo(merchantInfo);
            }
        }
        return orders;
    }

    //获取id商户订单信息
    @Override
    public List<Orders> getMerchantOrders(Long userId) {
        // 获取商户信息
        MerchantInfo merchantInfo = merchantInfoService.queryByUserId(userId);
        if (merchantInfo == null) {
            throw new RuntimeException("商户信息不存在");
        }

        // 查询该商户的所有订单
        List<Orders> orders = ordersDao.queryByMerchantId(merchantInfo.getId(), null);

        // 加载订单详细信息
        for (Orders order : orders) {
            // 获取订单项列表
            List<OrderItem> orderItems = orderItemDao.queryByOrderNumber(order.getOrderNumber());
            order.setOrderItems(orderItems);

            // 如果是外送订单，获取收货地址信息
            if (order.getDeliveryType() == 0 && order.getAddressId() != null) {
                Address address = ordersDao.loadOrderAddress(order.getAddressId());
                order.setAddress(address);
            }
        }
        return orders;
    }



    /**
     * 支付订单
     */
    @Override
    @Transactional
    public void payOrder(String orderNumber) {
        Orders order = ordersDao.getOrderDetail(orderNumber);
        if (order == null || order.getOrderStatus() != 0) {
            throw new RuntimeException("订单状态异常");
        }

        // 更新订单状态
        order.setOrderStatus(1);
        order.setPayTime(new Date());
        ordersDao.update(order);

        // 更新商品销量
        List<OrderItem> items = orderItemDao.queryByOrderNumber(orderNumber);
        for (OrderItem item : items) {
            commodityDao.updateSaleCount(item.getCommodityId(), item.getQuantity());
        }
    }

    /**
     * 商家发货
     */
    @Override
    @Transactional
    public void shipOrder(String orderNumber, String courierName, String courierNumber) {
        List<OrderItem> items = orderItemDao.queryByOrderNumber(orderNumber);
        for (OrderItem item : items) {
            item.setCourierName(courierName);
            item.setCourierNumber(courierNumber);
            item.setShippingTime(new Date());
            item.setItemStatus(1);
            orderItemDao.updateShipping(item);
        }
    }

    /**
     * 确认收货
     */
    @Override
    @Transactional
    public void confirmReceipt(String orderNumber) {
        List<OrderItem> items = orderItemDao.queryByOrderNumber(orderNumber);
        for (OrderItem item : items) {
            item.setSuccessTime(new Date());
            item.setItemStatus(2);
            orderItemDao.confirmReceipt(item);
        }

        Orders order = ordersDao.getOrderDetail(orderNumber);
        order.setOrderStatus(2);
        ordersDao.update(order);
    }


    // 商家出餐
    @Override
    @Transactional
    public void prepareMeal(String orderNumber) {
        Orders order = ordersDao.getOrderDetail(orderNumber);


        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        switch (order.getOrderStatus()) {
            case -1:
                throw new RuntimeException("订单已取消，无法操作");
            case 0:
                throw new RuntimeException("订单未支付，请先完成支付");
            case 1:
                // 待发货状态，可以继续操作
                break;
            case 2:
                throw new RuntimeException("订单已出餐，无法重复");
            case 3:
                throw new RuntimeException("订单已完成，无法操作");
            default:
                throw new RuntimeException("订单状态异常：" + order.getOrderStatus());
        }

        if (order.getDeliveryType() != 1) {
            throw new RuntimeException("非自取订单");
        }

        // 更新订单项状态
        List<OrderItem> items = orderItemDao.queryByOrderNumber(orderNumber);
        for (OrderItem item : items) {
            item.setItemStatus(1);  // 1表示已出餐
            item.setShippingTime(new Date());
            orderItemDao.updatePrepareStatus(item);
        }

        // 更新订单状态
        order.setOrderStatus(2);  // 2表示待取餐
        ordersDao.update(order);
    }


    // 确认取餐
    @Override
    @Transactional
    public void confirmPickup(String orderNumber) {
        Orders order = ordersDao.getOrderDetail(orderNumber);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        switch (order.getOrderStatus()) {
            case -1:
                throw new RuntimeException("订单已取消，无法操作");
            case 0:
                throw new RuntimeException("订单未支付，请先完成支付");
            case 1:
                throw new RuntimeException("订单已支付，无法重复");
            case 2:
                break;
            case 3:
                throw new RuntimeException("订单已完成，无法操作");
            default:
                throw new RuntimeException("订单状态异常：" + order.getOrderStatus());
        }
        if (order.getDeliveryType() != 1) {
            throw new RuntimeException("非自取订单");
        }


        // 更新订单项状态
        List<OrderItem> items = orderItemDao.queryByOrderNumber(orderNumber);
        for (OrderItem item : items) {
            item.setItemStatus(2);  // 2表示已完成
            item.setSuccessTime(new Date());
            orderItemDao.confirmReceipt(item);
        }

        // 更新订单状态
        order.setOrderStatus(3);  // 3表示已完成
        ordersDao.update(order);
    }


    // 取消支付
    @Override
    @Transactional
    public void cancelOrder(String orderNumber) {
        // 1. 查询订单
        Orders order = ordersDao.getOrderDetail(orderNumber);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 检查订单状态
        if (order.getOrderStatus() == -1) {
            throw new RuntimeException("订单已取消");
        }
        if (order.getOrderStatus() > 1) {
            throw new RuntimeException("订单已发货/配送中，无法取消");
        }

        // 3. 如果订单已支付，需要退款
//        if (order.getOrderStatus() == 1) {
//            this.handleAlipayRefund(order);
//        }

        // 4. 更新订单项状态
        List<OrderItem> items = orderItemDao.queryByOrderNumber(orderNumber);
        for (OrderItem item : items) {
            item.setItemStatus(3);  // 3表示已取消
            orderItemDao.updateStatus(item.getId(), 3);
        }

        // 5. 更新订单状态
        order.setOrderStatus(-1);  // -1表示已退款
        ordersDao.update(order);

        // 6. 恢复商品库存
        for (OrderItem item : items) {
            commodityDao.updateInventory(item.getCommodityId(), item.getQuantity());
        }
    }










    /**
     * 处理支付宝退款
     */
    private void handleAlipayRefund(Orders order) {
        int maxRetries = 3;
        int retryCount = 0;
        long retryDelay = 1000; // 1秒

        while (retryCount < maxRetries) {

            try {
                AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
                JSONObject bizContent = new JSONObject();
                bizContent.put("out_trade_no", order.getOrderNumber());
                bizContent.put("refund_amount", order.getPayAmount().toString());
                bizContent.put("refund_reason", "正常退款");
                request.setBizContent(bizContent.toString());

                AlipayTradeRefundResponse response = alipayClient.execute(request);
                if (response.isSuccess()) {
                    log.info("订单{}退款成功", order.getOrderNumber());
                    return;
                }

                // 处理特定错误码
                if ("ACQ.SYSTEM_ERROR".equals(response.getSubCode())) {
                    log.warn("订单{}退款遇到系统错误，准备重试", order.getOrderNumber());
                    retryCount++;
                    if (retryCount < maxRetries) {
                        Thread.sleep(retryDelay);
                        retryDelay *= 2; // 指数退避
                        continue;
                    }
                }

                throw new RuntimeException("退款失败：" + response.getSubMsg());

            } catch (Exception e) {
                log.error("订单{}退款处理异常", order.getOrderNumber(), e);
                retryCount++;
                if (retryCount < maxRetries) {
                    try {
                        Thread.sleep(retryDelay);
                        retryDelay *= 2;
                        continue;
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("退款处理被中断");
                    }
                }
                throw new RuntimeException("退款异常，请稍后重试");
            }
        }

        throw new RuntimeException("退款失败，已重试" + maxRetries + "次");
    }


    /**
     * 生成订单号（8位）
     */
    private String generateOrderNumber(Long userId) {
        // 获取当前时间戳的后4位
        long timestamp = System.currentTimeMillis() % 10000;

        // 生成2位随机数
        Random random = new Random();
        String randomNum = String.format("%02d", random.nextInt(100));

        // 获取用户ID的后2位
        String userIdSuffix = String.format("%02d", userId % 100);

        // 组合：时间戳后4位 + 用户ID后2位 + 2位随机数
        return String.format("%04d%s%s", timestamp, userIdSuffix, randomNum);
    }

    private BigDecimal calculateExtraPrice(OrderItem item) {
        BigDecimal extraPrice = BigDecimal.ZERO;

        // 根据杯型加价
        if ("中杯".equals(item.getCupSize())) {
            extraPrice = extraPrice.add(new BigDecimal("3.00"));
        } else if ("大杯".equals(item.getCupSize())) {
            extraPrice = extraPrice.add(new BigDecimal("6.00"));
        }

        // 根据咖啡豆加价
        if ("埃塞俄比亚豆".equals(item.getCoffeeBean())) {
            extraPrice = extraPrice.add(new BigDecimal("2.00"));
        } else if ("蓝山咖啡豆".equals(item.getCoffeeBean())) {
            extraPrice = extraPrice.add(new BigDecimal("5.00"));
        }

        // 根据浓度加价
        if ("重度".equals(item.getIntensity())) {
            extraPrice = extraPrice.add(new BigDecimal("2.00"));
        }

        return extraPrice;
    }



}
